package com.example.ddd.domain.service;

import com.example.ddd.infrastructure.lock.DistributedLockManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * 订单锁服务 - 领域服务
 * 提供订单相关的分布式锁操作
 */
@Service
public class OrderLockService {

    private static final String ORDER_PAY_LOCK_PREFIX = "order:pay:";
    private static final String ORDER_CANCEL_LOCK_PREFIX = "order:cancel:";
    private static final String ORDER_INVENTORY_LOCK_PREFIX = "order:inventory:";
    
    private final DistributedLockManager distributedLockManager;

    @Autowired
    public OrderLockService(DistributedLockManager distributedLockManager) {
        this.distributedLockManager = distributedLockManager;
    }

    /**
     * 尝试获取订单支付锁
     * @param orderId 订单ID
     * @return 是否获取成功
     */
    public boolean tryLockOrderPayment(String orderId) {
        String lockKey = ORDER_PAY_LOCK_PREFIX + orderId;
        // 尝试获取锁，最多等待5秒，锁持有时间30秒
        return distributedLockManager.lock(lockKey, 5, 30, TimeUnit.SECONDS);
    }

    /**
     * 释放订单支付锁
     * @param orderId 订单ID
     */
    public void releaseOrderPaymentLock(String orderId) {
        String lockKey = ORDER_PAY_LOCK_PREFIX + orderId;
        distributedLockManager.unlock(lockKey);
    }

    /**
     * 尝试获取订单取消锁
     * @param orderId 订单ID
     * @return 是否获取成功
     */
    public boolean tryLockOrderCancellation(String orderId) {
        String lockKey = ORDER_CANCEL_LOCK_PREFIX + orderId;
        // 尝试获取锁，最多等待5秒，锁持有时间30秒
        return distributedLockManager.lock(lockKey, 5, 30, TimeUnit.SECONDS);
    }

    /**
     * 释放订单取消锁
     * @param orderId 订单ID
     */
    public void releaseOrderCancellationLock(String orderId) {
        String lockKey = ORDER_CANCEL_LOCK_PREFIX + orderId;
        distributedLockManager.unlock(lockKey);
    }

    /**
     * 尝试获取库存锁
     * @param productId 产品ID
     * @return 是否获取成功
     */
    public boolean tryLockInventory(String productId) {
        String lockKey = ORDER_INVENTORY_LOCK_PREFIX + productId;
        // 尝试获取锁，最多等待3秒，锁持有时间10秒
        return distributedLockManager.lock(lockKey, 3, 10, TimeUnit.SECONDS);
    }

    /**
     * 释放库存锁
     * @param productId 产品ID
     */
    public void releaseInventoryLock(String productId) {
        String lockKey = ORDER_INVENTORY_LOCK_PREFIX + productId;
        distributedLockManager.unlock(lockKey);
    }

    /**
     * 执行加锁的订单操作
     * @param orderId 订单ID
     * @param action 要执行的操作
     * @param <T> 操作返回类型
     * @return 操作结果，如果获取锁失败则返回null
     */
    public <T> T executeWithOrderLock(String orderId, DistributedLockManager.LockCallback<T> action) {
        String lockKey = ORDER_PAY_LOCK_PREFIX + orderId;
        return distributedLockManager.executeWithLock(lockKey, 5, 30, TimeUnit.SECONDS, action);
    }
}